package com.cat.ai.controller;

import com.alibaba.cloud.ai.agent.Agent;
import com.alibaba.cloud.ai.dashscope.agent.DashScopeAgent;
import com.alibaba.cloud.ai.dashscope.agent.DashScopeAgentOptions;
import com.alibaba.cloud.ai.dashscope.api.DashScopeAgentApi;
import com.cat.ai.repository.ChatHistoryRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.Media;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.MimeType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.Objects;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;

/**
 * @Author 猫大仙
 */
@RequiredArgsConstructor
@RequestMapping("/ai")
@RestController
public class ChatController {

//  private final DashScopeAgent agent;
//    private final ChatHistoryRepository chatHistoryRepository;

//    @Value("${spring.ai.dashscope.agent.app-id}")
//    private String appId;
//
//    public ChatController(DashScopeAgentApi dashscopeAgentApi,
//                          ChatHistoryRepository chatHistoryRepository) {
//        this.agent = new DashScopeAgent(dashscopeAgentApi);
//        this.chatHistoryRepository = chatHistoryRepository;
//    }
//
//
//
//
//
//    @RequestMapping(value = "/chat",produces = "text/html;charset=utf-8")
//    public Flux<String> chat(@RequestParam(value = "files",required = false) List<MultipartFile> files,
//                             @RequestParam("prompt") String prompt,
//                             @RequestParam("chatId") String chatId) {
//        chatHistoryRepository.save("chat", chatId);
//
//        return agent.stream(new Prompt(
//                prompt,
//                DashScopeAgentOptions.builder()
//                        .withAppId(appId)
//                        .withSessionId(chatId)
//                        .withHasThoughts(false)
//                        // 若支持上下文ID可在此添加
//                        .build()
//        )).map(response -> {
//            AssistantMessage appOutput = response.getResult().getOutput();
//            return appOutput.getText();
//        });
//    }

    @Qualifier("client")
    private final ChatClient client;

    private final ChatHistoryRepository chatHistoryRepository;

    @RequestMapping(value = "/chat",produces = "text/html;charset=utf-8")
    public Flux<String> chat(@RequestParam(value = "files",required = false) List<MultipartFile> files,
                             @RequestParam("prompt") String prompt,
                             @RequestParam("chatId") String chatId) {
        chatHistoryRepository.save("chat", chatId);

        if(files == null || files.isEmpty()){
            return textChat(prompt,chatId);
        }else {
            return multipartChat(files,prompt,chatId);
        }
    }

    private Flux<String> textChat(String prompt,String chatId) {

                return client.prompt()
                .user(prompt)
                .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY,chatId))
                .stream()
                .content();
    }
    private Flux<String> multipartChat(List<MultipartFile> files,String prompt,String chatId) {
        List<Media> list = files.stream().map(file -> new Media(
                MimeType.valueOf(Objects.requireNonNull(file.getContentType()))
                , file.getResource())).toList();
        return client.prompt()
                .user(p->p.text(prompt).media(list.toArray(Media[]::new)))
                .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY,chatId))
                .stream()
                .content();
    }

}
